package jvm.autoMemoryManagement;

/**
 * VM参数：-XX:+UseSerialGC
 * @author msi
 */
public class TestSerialGCAllocation {

    private static final int _1MB = 1024 * 1024;

    /**
     * VM参数：-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
     * 堆大小为 20M, 10M为新生代大小， 10M为老年代大小， Eden:Survivor1:Survivor2 = 8:1:1 也就是新生代实际可用 9M
     */
    public static void testAllocation() {
        byte[] allocation1, allocation2, allocation3, allocation4;
        allocation1 = new byte[2 * _1MB];
        allocation2 = new byte[2 * _1MB];
        allocation3 = new byte[2 * _1MB];
        allocation4 = new byte[4 * _1MB];  //出现一次Minor GC
    }
    /**
     * 结果显示小对象会优先分配到Eden区,当allocation4分配不了时，会触发Minor GC，但是由于堆中全是存活对象，就会将all1,all2,all3给移动到老年区中。
     */

    public static void main(String[] args) {
        //小对象优先分配在Eden区
//        testAllocation();

        //大对象优先分配在老年区
//        testPretenureSizeThreshold();

        //长期存活的对象进入老年代
//        testTenuringThreshold();

        //动态年龄判断
//        testTenuringThreshold2();

        //空间分配担保
        testHandlePromotion();
    }

    /**
     * VM参数：-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
     * -XX:PretenureSizeThreshold=3145728
     * 设置大对象阈值为3MB 该参数只对 Serial和ParNew生效
     */
    public static void testPretenureSizeThreshold() {
        byte[] allocation;
        allocation = new byte[4 * _1MB];  //直接分配在老年代中
    }

    /**
     * VM参数：-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=1
     * -XX:+PrintTenuringDistribution
     * 设置长期存活的对象进入老年代
     */
    public static void testTenuringThreshold() {
        byte[] allocation1, allocation2, allocation3;
        allocation1 = new byte[_1MB / 4];  // 什么时候进入老年代决定于XX:MaxTenuringThreshold设置
        allocation2 = new byte[4 * _1MB];
        allocation3 = new byte[4 * _1MB];
        allocation3 = null;
        allocation3 = new byte[4 * _1MB];
    }
    /**
     * 结果all1和all2都会在老年代中，因为分配all3时进行了2次GC，所以年龄>1，进入老年区。
     */

    /**
     * VM参数：-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15
     * -XX:+PrintTenuringDistribution
     */
    public static void testTenuringThreshold2() {
        byte[] allocation1, allocation2, allocation3, allocation4;
        allocation1 = new byte[_1MB / 4];   // allocation1+allocation2大于survivor空间一半
        allocation2 = new byte[_1MB / 4];
        allocation3 = new byte[4 * _1MB];
        allocation4 = new byte[4 * _1MB];
        allocation4 = null;
        allocation4 = new byte[4 * _1MB];
    }
    /**
     * 动态年龄判断，当Survivor区中的一半的对象年龄都大于某值的时候，会将这个对象全部移动到老年区，无论到没到达年龄限制，all1,all2被移动到老年区并且Survivor区为空
     */

    /**
     * VM参数：-Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:-HandlePromotionFailure
     * -XX:-HandlePromotionFailure=true
     */
    public static void testHandlePromotion() {
        byte[] allocation1, allocation2, allocation3, allocation4, allocation5, allocation6, allocation7;
        allocation1 = new byte[2 * _1MB];
        allocation2 = new byte[2 * _1MB];
        allocation3 = new byte[2 * _1MB];
        allocation1 = null;
        allocation4 = new byte[2 * _1MB];
        allocation5 = new byte[2 * _1MB];
        allocation6 = new byte[2 * _1MB];
        allocation4 = null;
        allocation5 = null;
        allocation6 = null;
        allocation7 = new byte[2 * _1MB];
    }



}
